/**
 * Copyright 2010-2012 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.infinitus.activity.util;



import org.springframework.util.MultiValueMap;
import java.util.*;

/**
 * <p>
 * <b>OpenApiHelper</b> OPEN API助手，用来处理POST BODY和签名
 * </p>
 *
 * @since 2012-7-10
 * @author zhengping_wang
 * @version $Id: OpenApiHelper.java 5296 2014-07-22 02:39:07Z wilson $
 */
public class OpenApiHelper {

	public final static String APP_KEY = "app_key";

	public final static String SIGN = "sign";

	public final static String TIMESTAMP = "timestamp";

	public final static String SESSION = "session";

	public final static String SESSION_USER = "session_user";

	public final static String FORMAT = "format";


	public final static String FORMAT_JSON = "json";

	public final static String VERSION = "v";

	public final static String SIGN_METHOD = "sign_method";

	public final static String SIGN_METHOD_MD5 = "md5";

	public final static String SIGN_METHOD_HMAC = "hmac";

	/**
	 * 组织OpenAPI参数
	 * 
	 * @param appId
	 *            在UIM中注册的APP_ID
	 * @param appSecret
	 *            UIM系统中注册的应用密钥
	 * @param sessionKey
	 *            CAS系统分配给登录用户的PT
	 * @param version
	 *            API的版本号，默认不填是1.0
	 * @param format
	 *            返回数据的格式，可选json或xml，目前支持json
	 * @param signMethod
	 *            数据签名算法，支持md5或hmac，默认是md5
	 * @param postParams
	 *            本次请求的POST的参数
	 * @return 所有参数的签名
	 */
	public static String getOpenApiParamsMap(String appId, String appSecret, String sessionKey, String sessionUser,
			String version, String format, String signMethod, String locale, MultiValueMap<String, String> postParams) {
		TreeMap<String, String> params = new TreeMap<String, String>();
		params.put(APP_KEY, appId);
		params.put(TIMESTAMP, Long.toString((EnvironmentUtils.getCurrentTime()).getTime()));
		// 以下是可选参数
		if (StringUtils.isNotEmpty(sessionKey)) {
			params.put(SESSION, sessionKey);
		}

		if (StringUtils.isNotEmpty(sessionUser)) {
			params.put(SESSION_USER, sessionUser);
		}

		if (StringUtils.isNotEmpty(version)) {
			params.put(VERSION, version);
		}
		if (StringUtils.isNotEmpty(format)) {
			params.put(FORMAT, format);
		}
		if (StringUtils.isNotEmpty(signMethod)) {
			params.put(SIGN_METHOD, signMethod);
		}
		if (StringUtils.isNotEmpty(locale)) {
			params.put("locale", locale);
		}

		StringBuffer result = new StringBuffer();
		boolean firstParam = true;
		for (Map.Entry<String, String> entry : params.entrySet()) {
			String name = entry.getKey();
			String value = entry.getValue();
			if (!firstParam) {
				result.append("&");
			}
			firstParam = false;
			result.append(name).append("=").append(value);
		}

		// 业务参数
		if (null != postParams) {
			for (String key : postParams.keySet()) {
				// 合并多值
				List<String> values = postParams.get(key);

				// 如果同名参数多于1个，要按照值排序
				if (values.size() > 1) {
					Collections.sort(values);
				}
				
				StringBuffer str = new StringBuffer(values.get(0));
				for (int i = 1; i < values.size(); i++) {
					str.append(key).append(values.get(i));
				}
				params.put(key, str.toString());
			}
		}

		// 对参数签名
		// 密钥是macula_samples在应用表中对应的公钥
		String sign = "";
		if (StringUtils.isNotEmpty(signMethod) && SIGN_METHOD_HMAC.equals(signMethod)) {
			sign = SignatureUtils.hmacSignature(params, appSecret);
		} else {
			sign = SignatureUtils.md5Signature(params, appSecret);
		}

		result.append("&").append(SIGN).append("=").append(sign);

		return result.toString();
	}


}
